import React, { Component } from 'react';
import './view.scss'

/* 逻辑：
1，通过React.cloneElement把子组件复制出来并添加display，render出来
2，通过componentWillReceiveProps拿到子节点
3，通过componentDidUpdate检测到show的改变，从而操作子节点的class添加动画
*/
export default class View extends Component {
  constructor(props) {
    super(props)
    this.state = {
      children: React.cloneElement(props.children, { style: { display: props.show ? 'block' : 'none' }}),
      transitionName: props.name || 'fade-in'
    }

    this.hasClass = this.hasClass.bind(this)
    this.addClass = this.addClass.bind(this)
    this.removeClass = this.removeClass.bind(this)
    this.removeAnimateClass = this.removeAnimateClass.bind(this)
    this.didEnter = this.didEnter.bind(this)
    this.didLeave = this.didLeave.bind(this)
    this.beforeEnter = this.beforeEnter.bind(this)
    this.beforeLeave = this.beforeLeave.bind(this)

  }

  hasClass (el, className) {
    return el.classList ? el.classList.contains(className) : new RegExp('\\b' + className + '\\b').test(el.className)
  }
  addClass (el, className) {
    if (el.classList) el.classList.add(className)
    else if (!this.hasClass(el, className)) el.className += ' ' + className
  }
  removeClass (el, className) {
    if (el.classList) el.classList.remove(className)
    else el.className = el.className.replace(new RegExp('\\b' + className + '\\b', 'g'), '')
  }

  beforeEnter () {
    this.removeAnimateClass()
    this.el.removeEventListener('transitionend', this.didLeave)
    this.el.addEventListener('transitionend', this.didEnter)
  }
  beforeLeave () {
    this.removeAnimateClass()
    this.el.removeEventListener('transitionend', this.didEnter)
    this.el.addEventListener('transitionend', this.didLeave)
    // emit
    this.props.beforeLeave && this.props.beforeLeave()
  }
  didEnter () {
    this.removeAnimateClass()
    // emit
    this.props.didEnter && this.props.didEnter()
  }
  didLeave () {
    this.el.style.display = 'none'
    this.removeAnimateClass()
    // emit
    this.props.didLeave && this.props.didLeave()
  }

  removeAnimateClass () {
    this.removeClass(this.el, `${this.state.transitionName}-leave-start`)
    this.removeClass(this.el, `${this.state.transitionName}-leave-active`)
    this.removeClass(this.el, `${this.state.transitionName}-leave-end`)
    this.removeClass(this.el, `${this.state.transitionName}-enter-start`)
    this.removeClass(this.el, `${this.state.transitionName}-enter-active`)
    this.removeClass(this.el, `${this.state.transitionName}-enter-end`)
  }

  componentDidMount  (props) {
  }

  componentWillReceiveProps (nextProps) { // 处理show
    if (nextProps.show !== this.props.show) {
    this.setState({
      children: React.cloneElement(nextProps.children, Object.assign({ ref: (el) => { this.el = el }}))
    })
    }
  }
  componentDidUpdate (preProps) { // 处理style
    if (preProps.show !== this.props.show) {
    if (!preProps.show) {
      this.beforeEnter()
      this.addClass(this.el, `${this.state.transitionName}-enter-start`)
      this.addClass(this.el, `${this.state.transitionName}-enter-active`)
      requestAnimationFrame(() => {
        requestAnimationFrame(() => {
          this.addClass(this.el, `${this.state.transitionName}-enter-end`)
        })
      })
      this.el.style.display = 'block'
      // emit
      this.props.beforeEnter && this.props.beforeEnter()
    } else {
      this.beforeLeave()
      this.addClass(this.el, `${this.state.transitionName}-leave-start`)
      this.addClass(this.el, `${this.state.transitionName}-leave-active`)
      requestAnimationFrame(() => {
        requestAnimationFrame(() => {
          this.addClass(this.el, `${this.state.transitionName}-leave-end`)
        })
      })
    }
    }
  }
  render () {
    return this.state.children
  }
}
